package com.mcptt.http.auth.process;

import android.os.Handler;
import android.os.Message;

import com.cloudptt.api.product.log.Log;
import com.mcptt.config.callback.IAuthCallback;
import com.mcptt.http.auth.process.passwd.result.FirstGetResult;
import com.mcptt.http.auth.process.passwd.result.FirstPostResult;
import com.mcptt.http.auth.process.result.FinalResult;
import com.mcptt.http.operator.HttpOperator;
import com.mcptt.http.tool.EncryptionTool;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import okhttp3.Response;

public abstract class HttpSubProcessor
{
	public final static String LOGIN_ERR_LICENSE = "login_err_license";
	public final static int AUTH_SUC = 1;
	public final static int AUTH_FAILED = 2;

	public final static int REFRESH_SUC = 3;
	public final static int REFRESH_FAILED = 4;

	protected final static String Socp_Openid = "openid";
	protected final static String Socp_Ptt_Svr = "3gpp:mc:ptt_service";
	protected final static String Socp_Ptt_Key_Svr = "3gpp:mc:ptt_key_management_server";
	protected final static String Socp_Ptt_Config_Svr = "3gpp:mc:ptt_config_management_service";
	protected final static String Socp_Ptt_Group_Svr = "3gpp:mc:ptt_group_management_service";

	protected final static String Socp_Video_Svr = "3gpp:mc:video_service";
	protected final static String Socp_Video_Key_Svr = "3gpp:mc:video_key_management_service";
	protected final static String Socp_Video_Config_Svr = "3gpp:mc:video_config_management_service";
	protected final static String Socp_Video_Group_Svr = "3gpp:mc:video_group_management_service";

	protected final static String Socp_Data_Svr = "3gpp:mc:data_service";
	protected final static String Socp_Data_Key_Svr = "3gpp:mc:data_key_management_service";
	protected final static String Socp_Data_Config_Svr = "3gpp:mc:data_config_management_service";
	protected final static String Socp_Data_Group_Svr = "3gpp:mc:data_group_management_service";
	protected final static String Socp_Location_Svr = "3gpp:mc:location_management_service";

	protected HttpOperator operator = null;
	private String url = "";
	protected String socpStr = null;
	private String verifierCode = null;

	protected URI authUri = null;
	protected URI loginUri = null;
	protected URI tokenUri = null;

	// private String cookie = null;

	public HttpSubProcessor(URI authUri, URI loginUri, URI tokenUri)
	{
		this.operator = new HttpOperator();
		this.authUri = authUri;
		if(authUri != null)
		{
			this.initUrl(authUri.getHost(), authUri.getPort());
		}
		this.loginUri = loginUri;
		this.tokenUri = tokenUri;
		this.initSocpStr();
		this.initVerifierCode();
	}

	public abstract void runAuthorization(String clientId, String redirectUri,String mcId,String pwd) throws Exception;
	public abstract String getAcrStr();
	public abstract String getChallengeMethod();
	protected abstract void initSocpStr();
	protected abstract String getState();

	public void doAuthorization(String clientId, String redirectUri,String mcId,String pwd,IAuthCallback callback) throws Exception
	{
		this.callback = callback;
		runAuthorization(clientId,redirectUri,mcId,pwd);
		//	return finalResult;
	}


	public void doRefreshToken(String refreshToken,IAuthCallback callback) throws Exception
	{
		this.callback = callback;
		FinalResult result = doRefreshToken(refreshToken);
		Log.debug(HttpProcessor.class,  "doRefreshToken result = " + result);
		if(!result.isSuc())
		{
			String errStr = result.getErrStr();
			Exception e =  new HttpAuthFailedException("doRefreshToken",errStr);
			sendAuthResultMsg(REFRESH_FAILED,e);
			return;
		}
		Log.debug(HttpProcessor.class,  "result.checkReturnParamOk() = " + result.checkRefreshParamOk());
		if(!result.checkRefreshParamOk())
		{
			Exception e =  new HttpAuthFailedException("doRefreshToken","Return Param less");
			sendAuthResultMsg(REFRESH_FAILED,e);
			return;
		}
		sendAuthResultMsg(REFRESH_SUC,result);
	}



	public FinalResult doRefreshToken(String refreshToken) throws Exception
	{

		FinalResult result = null;
		Map<String,String> params = new HashMap<String,String>();
		params.put("grant_type", "refresh_token");
//		params.put("scope", getSocpStr());
		params.put("refresh_token", refreshToken);

		Response httpResponse = this.operator.httpPostRequest(tokenUri.toString(), params);
		int code = httpResponse.code();
		Log.debug(this.getClass(),"doRefreshToken code = " + code);
		if ( (code == 200
				|| code == 400)
				&& httpResponse.body() != null)
		{
			/* ���X�^���r�� */
			byte[] responseBytes = httpResponse.body().bytes(); // 获取字节数组
			Log.debug(this.getClass(), "doRefreshToken Byte Length: " + responseBytes.length);
			String desc = new String(responseBytes);
			Log.debug(this.getClass(),"doRefreshToken desc = " + desc);
			result = new FinalResult(code, desc);
		}
		else
		{
			String desc = "Error Response: "
					+ httpResponse.code();
			result = new FinalResult(code, desc);
		}

		return result;
	}

	protected void initUrl(String ip, int port)
	{
		StringBuffer strBuf = new StringBuffer("http://");
		strBuf.append(ip).append(":");
		strBuf.append(port);//.append("/idms/authorization");

		this.url = strBuf.toString();
	}

	public String getUrl(String subUrl)
	{
		if(subUrl != null
				&& subUrl.length() >0)
		{
			subUrl = subUrl.trim();
			if(subUrl.startsWith("/"))
			{
				return url + subUrl;//相对路径
			}
			else
			{
				return subUrl;//绝对路径
			}
		}
		return url;
	}

	private IAuthCallback callback = null;

	Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch(msg.what)
			{
				case AUTH_SUC:
					FinalResult finalResult = (FinalResult)msg.obj;
					if(callback != null)
					{
						callback.httpAuthSuc(IAuthCallback.Auth_Reg,finalResult);
					}
					break;
				case AUTH_FAILED:
					HttpAuthFailedException ex = (HttpAuthFailedException)msg.obj;
					if(callback != null)
					{
						callback.httpAuthFailed(IAuthCallback.Auth_Reg,ex.getCode(),ex.toString());
					}
					break;
				case REFRESH_SUC:
					finalResult = (FinalResult)msg.obj;
					if(callback != null)
					{
						callback.httpAuthSuc(IAuthCallback.Auth_Reg,finalResult);
					}
					break;
				case REFRESH_FAILED:
					ex = (HttpAuthFailedException)msg.obj;
					if(callback != null)
					{
						callback.httpAuthFailed(IAuthCallback.Auth_Reg,ex.getCode(),ex.toString());
					}
					break;
			}
		}
	};
	public void sendAuthResultMsg(int what,Object obj)
	{
		Message msg = handler.obtainMessage(what, obj);
		msg.sendToTarget();
	}

	protected void initVerifierCode()
	{
		Random ran = new Random();
		int a = ran.nextInt(99999999);
		int b = ran.nextInt(99999999);
		long l = a * 10000000L + b;
		this.verifierCode = String.valueOf(l);
//		this.verifierCode = "0x123456789abcdef";
	}

	public String getVerifierCode()
	{
		return verifierCode;
	}

	protected String getSocpStr()
	{
		return this.socpStr;
	}


}
